#include "stk_transport.h"
#include <string.h>

using namespace stk;

Transport::Transport()
{
    SetType(STK_FD_NAME_TRANSPORT);

    clear();
}

Transport::Transport(const Transport &src)
{
    *this = src;
}

Transport::Transport(const char *buf, int len)
{
    SetType(STK_FD_NAME_TRANSPORT);
    parse(buf, len);
}

Transport::~Transport()
{
    clear();
}

bool Transport::isvalid() const
{
    return !m_strMediaType.empty();
}

void Transport::clear()
{
    m_strMediaType   = "";
    m_strCastType    = "";
}

int32_t Transport::to_str (string &str)
{
    if (!isvalid())
    {
        printf("ERRO: <%010d> <%s.to_str> Invalid Buffer\n", GetSession(), GetTypeName());
        return -1;
    }

    if (!m_strMediaType.empty())
    {
        str += m_strMediaType;
    }

    if (!m_strCastType.empty())
    {
        str += ";";
        str += m_strCastType;
    }

    string strParams;
    m_listParams.to_str(strParams);

    str += strParams;

    return 0;
}

int32_t Transport::parse (const char *buf, int len)
{
    const char *cast_type;
    const char *comment;
    const char *trans_params;

    if (!buf)
    {
        printf("ERRO: <%010d> <%s.Parse> Invalid Buffer\n", GetSession(), GetTypeName());
        return -1;
    }

    clear();

    cast_type = strchr(buf, ';');

    if (!cast_type)
    {
        printf("ERRO: <%010d> <%s.Parse> Invalid Buffer\n", GetSession(), GetTypeName());
        return -1;
    }

    m_strMediaType.assign(buf, cast_type - buf);

    comment = strchr(cast_type + 1, ';');

    if (comment)
    {
        m_strCastType.assign(cast_type + 1, comment - cast_type - 1);
    }
    else
    {
        m_strCastType = cast_type + 1;
    }

    trans_params = comment;

    if (trans_params && strlen(trans_params) > 2)
    {
        string strParams = trans_params;

        if (m_listParams.parse_params (strParams) != 0)
        {
            clear();
            printf("ERRO: <%010d> <%s.Parse> Invalid Buffer\n", GetSession(), GetTypeName());
            return -1;
        }
    }


    return 0;                     /* ok */
}

Transport& Transport::operator = (const Transport &src)
{
    clear();

    m_strMediaType = src.m_strMediaType;
    m_strCastType  = src.m_strCastType;
    m_listParams   = src.m_listParams;
    MsgField::operator=(src);

    return *this;
}

void Transport::SetParamByName(const char *szName, const char *szValue)
{
    if (!szName || !szValue)
    {
        return;
    }

    string strParam = string(";") + string(szName) + string("=") + szValue;

    m_listParams.parse_params(strParam);
}

string Transport::GetParamByName(const char *szName)
{
    if (!szName)
    {
        return "";
    }

    MsgParam *pParam = m_listParams.get_byname(szName);

    if (!pParam)
    {
        return "";
    }

    return pParam->m_value;
}

void Transport::SetMode(const char *szValue)
{
    SetParamByName("mode", szValue);
}

void  Transport::SetDestination(const char *szValue)
{
    SetParamByName("destination", szValue);
}

void  Transport::SetSource(const char *szValue)
{
    SetParamByName("source", szValue);
}

void  Transport::SetServerPort(const char *szValue)
{
    SetParamByName("server_port", szValue);
}

void  Transport::SetClientPort(const char *szValue)
{
    SetParamByName("client_port", szValue);
}

void  Transport::SetSSrc(const char *szValue)
{
    SetParamByName("ssrc", szValue);
}

string Transport::GetMode()
{
    return GetParamByName("mode");
}

string Transport::GetDestination()
{
    return GetParamByName("destination");
}

string Transport::GetSource()
{
    return GetParamByName("source");
}

string Transport::GetServerPort()
{
    return GetParamByName("server_port");
}

string Transport::GetClientPort()
{
    return GetParamByName("client_port");
}

string Transport::GetSSrc()
{
    return GetParamByName("ssrc");
}
